home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 March / Macworld (1998-03) (Disk 1).dmg / Shareware World / Info / For Developers / GhostScript 5.10 / MacGS-510 / files / pdf_draw.ps < prev    next >
Text File  |  1997-09-27  |  12KB  |  450 lines

  1. %    Copyright (C) 1994, 1995, 1997 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % pdf_draw.ps
  16. % PDF drawing operations (graphics, text, and images).
  17.  
  18. % We don't handle the following PDF elements yet (identified by
  19. % page number in the reference manual):
  20. %    style strings (63-64), except in a few known fonts
  21. %    font descriptor resources (71-75), except for MissingWidth
  22. %    text clipping modes (104)
  23. %        What do these mean??
  24.  
  25. % We handle the following PDF 1.2 constructs:
  26. %    gs operator (but not functions)
  27.  
  28. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  29. .currentglobal true .setglobal
  30. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  31. GS_PDF_ProcSet begin
  32. pdfdict begin
  33.  
  34. % For simplicity, we use a single interpretation dictionary for all
  35. % PDF graphics operations, even though this is too liberal.
  36. /drawopdict 100 dict def
  37.  
  38. % ================================ Graphics ================================ %
  39.  
  40. % ---------------- Functions ---------------- %
  41.  
  42. /resolvefunction {    % <fndict> resolvefunction <function>
  43.         % Don't lose our place in PDFfile.
  44.   PDFfile fileposition exch
  45.   dup true resolvestream
  46.         % The stream isn't positionable, so read all the data now.
  47.         % Note that we only support FunctionType 0.
  48.         % Stack: filepos fndict stream
  49.   1 index /Range get length 2 idiv 2 index /BitsPerSample get mul
  50.   2 index /Size get { mul } forall
  51.   7 add 8 idiv string
  52.   1 index exch readstring pop exch closefile
  53.         % Stack: filepos fndict data
  54.   exch dup length 1 add dict .copydict
  55.   dup /DataSource 4 -1 roll put
  56.   .buildfunction
  57.   exch PDFfile exch setfileposition
  58. } bdef
  59.  
  60. % ---------------- Graphics state management ---------------- %
  61.  
  62. drawopdict begin
  63.             % Graphics state stack
  64.   /q { q } def
  65.   /Q { Q } def
  66.             % Graphics state setting
  67.   /cm { cm } def
  68.   /i { i } def
  69.   /J { J } def
  70.   /d { d } def
  71.   /j { j } def
  72.   /w { w } def
  73.   /M { M } def
  74.   /gs { gs } def
  75. end
  76.  
  77. /gsparamdict mark
  78.   /Type { pop }
  79.   /SA { /setstrokeadjust 1 # }
  80.   /OP { /setoverprint 1 # }
  81.   /BG
  82.    { dup /Identity eq
  83.       { pop { } /setblackgeneration 1 #
  84.       }
  85.       {        %****** DUMMY ******
  86.     pop
  87.       }
  88.      ifelse
  89.    }
  90.   /UCR
  91.    { dup /Identity eq
  92.       { pop { } /setundercolorremoval 1 #
  93.       }
  94.       {        %****** DUMMY ******
  95.     pop
  96.       }
  97.      ifelse
  98.    }
  99.   /TR
  100.    { dup /Identity eq
  101.       { pop { } /settransfer 1 #
  102.       }
  103.       {        %****** DUMMY ******
  104.     pop
  105.       }
  106.      ifelse
  107.    }
  108.   /HT
  109.    { dup /Default eq
  110.       { pop /.setdefaultscreen 0 #
  111.       }
  112.       {        %****** DUMMY ******
  113.     pop
  114.       }
  115.      ifelse
  116.    }
  117.   /HTP { oget aload pop /sethalftonephase 2 # }
  118. .dicttomark readonly def
  119. /gs            % <gsres> gs -
  120.  { Page /ExtGState rget
  121.     {  { oforce exch gsparamdict exch .knownget { exec } { pop } ifelse }
  122.       forall
  123.     }
  124.    if
  125.  } bdef
  126.  
  127. % ---------------- Color setting ---------------- %
  128.  
  129. /csncompdict mark
  130.   /DeviceGray 1
  131.   /CalGray 1
  132.   /DeviceRGB 3
  133.   /CalRGB 3
  134.   /Lab 3
  135.   /DeviceCMYK 4
  136.   /CalCMYK 4
  137.   /Separation 1
  138. .dicttomark readonly def
  139.  
  140. /csrdict mark
  141.   /DeviceGray {
  142.     /DefaultGray Page /ColorSpace rget { exch pop } if
  143.   }
  144.   /CalGray { }
  145.   /DeviceRGB {
  146.     /DefaultRGB Page /ColorSpace rget { exch pop } if
  147.   }
  148.   /CalRGB { }
  149.   /Lab { }
  150.   /DeviceCMYK { }
  151.   /CalCMYK { }
  152.   /Indexed    %****** SHOULD RESOLVE BASE SPACE *****
  153.    { dup 3 oget dup type /stringtype eq
  154.       { pop
  155.       }
  156.       {        % The color lookup table is a stream.
  157.         % Get its contents.  Don't lose our place in PDFfile.
  158.     PDFfile fileposition 3 1 roll
  159.     true resolvestream
  160.     1 index 2 get 1 add
  161.     csncompdict 3 index 1 get
  162.       dup type /arraytype eq { 0 get } if get mul
  163.     string readstring pop
  164.         % Stack: cspace filepos table
  165.     1 index 3 3 -1 roll put
  166.     exch PDFfile exch setfileposition
  167.       }
  168.      ifelse
  169.    }
  170.   /Pattern
  171.    { dup type /nametype ne
  172.       { dup length 1 ge
  173.      { 1 get resolvecolorspace
  174.        /Pattern exch 2 array astore
  175.      }
  176.     if
  177.       }
  178.      if
  179.    }
  180.   /Separation    %****** SHOULD RESOLVE ALTERNATIVE SPACE ******
  181.    {        % Resolve the tintTransform function.
  182.      dup 3 oget resolvefunction
  183.      1 index 3 3 -1 roll put
  184.    }
  185. .dicttomark readonly def
  186.  
  187. /csgray            % <op> <csop> csgray -
  188.  { /DeviceGray resolvecolorspace
  189.    dup /DeviceGray eq { pop } { exch 3 -1 roll } ifelse
  190.    pop cvx exec
  191.  } bdef
  192. /csrgb            % <op> <csop> csrgb -
  193.  { /DeviceRGB resolvecolorspace
  194.    dup /DeviceRGB eq { pop } { exch 3 -1 roll } ifelse
  195.    pop cvx exec
  196.  } bdef
  197. /cscmyk            % <op> <csop> cscmyk -
  198.  { pop cvx exec
  199.  } bdef
  200. /csresolve        % <csresourcename> csresolve <cspace>
  201.  { dup Page /ColorSpace rget
  202.     { exch pop resolvecolorspace }
  203.     { /undefined cvx signalerror }
  204.    ifelse
  205.  } bdef
  206. /resolvecolorspace {    % <cspace> resolvecolorspace <cspace'>
  207.   dup dup type /arraytype eq { 0 get } if
  208.   //csrdict exch .knownget {
  209.     exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
  210.   } {
  211.     csresolve
  212.   } ifelse
  213. } bdef
  214.  
  215. /cset        % <c0> ... [- <sc1> <sc2> <sc3> <sc4> <sc5>] cset -
  216.  {        % We can't really make sc[n] and SC[N] work, because
  217.         % the color space information isn't available at
  218.         % conversion time; so we hack it by assuming that
  219.         % all the operands on the stack are used, and that
  220.         % if the top operand is a name, it's a Pattern resource.
  221.    1 index type /nametype eq
  222.     { exch Page /Pattern rget { resolvepattern } { null } ifelse exch }
  223.    if
  224.    count 1 sub get exec
  225.  } bdef
  226. /resolvepattern        % <patternstreamdict> resolvepattern <patterndict>
  227.  {        % Don't do the resolvestream now: just capture the data
  228.         % from the file if necessary.
  229.    dup length dict copy
  230.    dup /FilePosition .knownget
  231.     { 1 index /File get dup fileposition 3 1 roll
  232.         % Stack: dict savepos pos file
  233.       dup 3 -1 roll setfileposition
  234.       dup 3 index /Length get string readstring pop
  235.         % Stack: dict savepos file string
  236.       3 1 roll exch setfileposition
  237.       1 index /File 3 -1 roll put
  238.       dup /FilePosition undef
  239.     }
  240.    if
  241.    dup /PaintProc
  242.     { false resolvestream pdfopdict .pdfrun
  243.     }
  244.    put
  245.  } bdef
  246.  
  247. drawopdict begin
  248.   /g { /g { cs sc1 } csgray } bdef
  249.   /rg { /rg { cs sc3 } csrgb } bdef
  250.   /k { /k { cs sc4 } cscmyk } bdef
  251.   /cs { csresolve cs } bdef
  252.   /sc { { null sc1 sc2 sc3 sc4 sc5 } cset } bdef
  253.   /scn /sc load def
  254.   /G { /G { CS SC1 } csgray } bdef
  255.   /RG { /RG { CS SC3 } csrgb } bdef
  256.   /K { /K { CS SC4 } cscmyk } bdef
  257.   /CS { csresolve CS } bdef
  258.   /SC { { null SC1 SC2 SC3 SC4 SC5 } cset } bdef
  259.   /SCN /SC load def
  260. end
  261.  
  262. % ---------------- Paths ---------------- %
  263.  
  264. drawopdict begin
  265.             % Path construction
  266.   /m { m } def
  267.   /l { l } def
  268.   /c { c } def
  269.   /v { v } def
  270.   /y { y } def
  271.   /re { re } def
  272.   /h { h } def
  273.             % Path painting and clipping
  274.   /n { n } def
  275.   /S { S } def
  276.   /s { s } def
  277.   /f { f } def
  278.   /f* { f* } def
  279.   /B { B } def
  280.   /b { b } def
  281.   /B* { B* } def
  282.   /b* { b* } def
  283.   /W { W } def
  284.   /W* { W* } def
  285. end
  286.  
  287. % ---------------- XObjects ---------------- %
  288.  
  289. /xobjectprocs mark        % <dict> -proc- -
  290.   /Image { DoImage }
  291.   /Form { DoForm }
  292. .dicttomark readonly def
  293.  
  294. /defaultdecodedict mark
  295.   /DeviceGray [0 1] readonly
  296.   /CalGray 1 index
  297.   /DeviceRGB [0 1 0 1 0 1] readonly
  298.   /CalRGB 1 index
  299.   /Lab
  300.    { 0 100 2 index 1 get /Range .knownget not { {-100 100 -100 100} } if
  301.      aload pop 6 array astore readonly
  302.    } bind
  303.   /DeviceCMYK [0 1 0 1 0 1 0 1] readonly
  304.   /CalCMYK 1 index
  305.   /Separation [0 1] readonly
  306. .dicttomark readonly def
  307.  
  308. /DoImage
  309.  { dup length dict
  310.    1 index /ColorSpace knownoget
  311.     { resolvecolorspace
  312.       dup type /arraytype eq { dup length 1 eq { 0 get } if } if
  313.       exch begin /ColorSpace exch def
  314.     }
  315.     { begin
  316.     }
  317.    ifelse
  318.    /ImageType 1 def
  319.         % Always define ImageMask appropriately.
  320.    dup /ImageMask knownoget dup { and } if
  321.      /ImageMask exch def
  322.    /Width 2 copy oget def
  323.    /Height 2 copy oget def
  324.    /BitsPerComponent 2 copy oget def
  325.    /Decode 2 copy knownoget not
  326.     {        % Decode is required for the PostScript image operators.
  327.       ImageMask
  328.        { [0 1]
  329.        }
  330.        { ColorSpace dup type /arraytype eq { 0 get } if dup /Indexed eq
  331.       { pop [ 0 1 BitsPerComponent bitshift 1 sub ] }
  332.       { defaultdecodedict exch get exec }
  333.      ifelse
  334.        }
  335.       ifelse
  336.     }
  337.    if def
  338.    /Interpolate 2 copy knownoget { def } { pop } ifelse
  339.    /ImageMatrix Width 0 0 Height neg 0 Height 6 array astore def
  340.         % Define DataSource as the width of the row buffer,
  341.         % which is what is needed if we're writing PostScript.
  342.    /DataSource 
  343.      Width BitsPerComponent mul
  344.      ImageMask not { Decode length 2 idiv mul } if
  345.      7 add 8 idiv
  346.    def
  347.         % Even though we're going to read data,
  348.         % pass false to resolvestream so that
  349.         % it doesn't try to use Length (which may not be present).
  350.    false resolvestream /Is_stream exch store
  351.    currentdict end ID
  352.  } bdef
  353. % Redefine Is, which constructs the data source for the image,
  354. % to retrieve the stream.  (pdf_2ps.ps redefines Is to copy the data too.)
  355. userdict /Is_stream null put
  356. /Is        % <imagedict> Is <imagedict> <datasource>
  357.  { Is_stream
  358.  } bdef
  359.  
  360. /DoForm
  361.  { dup [ /pop load 2 index
  362.     { false resolvestream pdfopdict .pdfrun }
  363.    aload pop ] cvx /PaintProc exch put
  364.    execform
  365.  } bdef
  366.  
  367. drawopdict begin
  368.   /Do
  369.     { PDFfile fileposition exch
  370.       dup Page /XObject rget not { /undefined cvx signalerror } if
  371.       exch pop dup /Subtype get xobjectprocs exch get exec
  372.       PDFfile exch setfileposition
  373.     } bdef
  374. end
  375.  
  376. % ---------------- In-line images ---------------- %
  377.  
  378. % Undo the abbreviations in an in-line image dictionary.
  379. % Note that these can appear as keys, values, or members of array values.
  380. % /I is ambiguous; we check specially for it below.
  381. /unabbrevdict mark
  382.     % Top-level dictionary keys
  383.   /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  384.   /F /Filter  /H /Height  /IM /ImageMask  /W /Width
  385.     % Values
  386.   /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  387.   /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  388.   /DCT /DCTDecode  /CMYK /DeviceCMYK  /G /DeviceGray  /RGB /DeviceRGB
  389.   /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
  390. .dicttomark readonly def
  391. /unabbrev        % <obj> unabbrev <obj'>
  392.  { dup type /nametype eq
  393.     { unabbrevdict 1 index .knownget { exch pop } if
  394.     }
  395.     { dup type /arraytype eq
  396.        { dup 0 1 2 index length 1 sub
  397.       { 2 copy get unabbrev put dup
  398.       }
  399.      for pop
  400.        }
  401.       if
  402.     }
  403.    ifelse
  404.  } bdef
  405.  
  406. drawopdict begin
  407.   /BI { mark } bdef
  408.   /ID
  409.     { counttomark
  410.        { counttomark 1 roll
  411.      dup /I eq { pop /Interpolate } { unabbrev } ifelse
  412.        }
  413.       repeat
  414.       /File PDFsource
  415.       .dicttomark DoImage
  416.       PDFsource token pop /EI ne { /ID cvx /syntaxerror signalerror } if
  417.     } bdef
  418. end
  419.  
  420. % ================================ Text ================================ %
  421.  
  422. drawopdict begin
  423.             % Text control
  424.   /BT { BT } def
  425.   /ET { ET } def
  426.   /Tc { Tc } def
  427.   /TL { TL } def
  428.   /Tr { Tr } def
  429.   /Ts { Ts } def
  430.   /Tw { Tw } def
  431.   /Tz { Tz } def
  432.             % Text positioning
  433.   /Td { Td } def
  434.   /TD { TD } def
  435.   /Tm { Tm } def
  436.   /T* { T* } def
  437.             % Text painting
  438.   /Tj { Tj } def
  439.   /' { ' } def
  440.   /" { " } def
  441.   /TJ { mark exch aload pop TJ } def
  442. end
  443.  
  444. end            % pdfdict
  445. end            % GS_PDF_ProcSet
  446. .setglobal
  447.